﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using CDSBDemandControl.Presenter;
using CDSBDemandControl.Model;
using System.Drawing;
using System.Web.UI.HtmlControls;

namespace CDSBDemandControl.View.Web.PaginasInternas
{
    public partial class ScenariosAndTasks : System.Web.UI.Page, IDiscriminatorDemand
    {
        private Presenter.DiscriminatorDemand Presenter;

        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Cache.SetExpires(DateTime.Now.Subtract(new TimeSpan(24, 0, 0)));
            Response.Cache.SetCacheability(HttpCacheability.NoCache);

            if (!this.IsPostBack || this.Session["Presenter"] == null)
            {
                this.Presenter = new DiscriminatorDemand(this);

                this.Session["Presenter"] = this.Presenter;

                if (!this.IsPostBack) this.ListarScenariosAndTasks();
            }
            else
            {
                this.Presenter = (Presenter.DiscriminatorDemand)this.Session["Presenter"];
                this.Presenter.ResetView(this);
            }

        }

        private void ListarScenariosAndTasks()
        {
            this.Presenter.ListarScenariosAndTasks();
        }

        void IDiscriminatorDemand.ExibirScenariosAndTasks(List<CDSBDemandControl.Model.ScenarioModel> scenarios)
        {
            scenarios = scenarios.OrderBy(rev => rev.Project).ToList();

            gridScenarios.DataSource = scenarios;
            gridScenarios.DataBind();

            this.ExibirObservacao("Scenarios e Tasks Em Desenvolvimento ou Aprovado para Desenvolvimento");

            // Exibe a data da última atualização
            (this.Master.FindControl("LblUltimoUpdate") as Label).Text = "Última atualização em: " + this.Presenter.ScenariosAndTasksLastUpdate.ToShortDateString() + " as " + this.Presenter.ScenariosAndTasksLastUpdate.ToShortTimeString();

        }

        private void ExibirObservacao(string obs)
        {
            this.LblObsOrdenacao.Text = obs;
            this.LblObsOrdenacao.Visible = this.LblObsOrdenacao.Text.Length > 0 ? true : false;
        }

        #region IDiscriminatorDemand Members

        void IDiscriminatorDemand.ExibirFila(IEnumerable<CDSBDemandControl.Model.DemandModel> demandModels)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirEsteira(IEnumerable<CDSBDemandControl.Model.DemandModel> demandModels)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirRanking(IEnumerable<CDSBDemandControl.Model.DeveloperModel> developers, IEnumerable<CDSBDemandControl.Model.DeveloperModel> leaders, IEnumerable<CDSBDemandControl.Model.DeveloperModel> focalpoints)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirAtrasos(IEnumerable<CDSBDemandControl.Model.DemandModel> PendingDemands, IEnumerable<CDSBDemandControl.Model.DemandModel> Concludeddemands)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirFaturamento(List<CDSBDemandControl.Model.BillingModel> billing, bool canSeeBilling)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirCodeReview(IEnumerable<CDSBDemandControl.Model.DemandModel> WorkItemsWithCodeReview, IEnumerable<CDSBDemandControl.Model.DemandModel> WorkItemsWithoutCodeReview)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirBugsdeProducao(IEnumerable<CDSBDemandControl.Model.DemandModel> demandModels)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirListaDisp(IEnumerable<CDSBDemandControl.Model.DemandModel> list, IEnumerable<CDSBDemandControl.Model.DeveloperModel> modelAusencias, List<DateTime> fer)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirBugsdeProducaoUltimoMes(List<CDSBDemandControl.Model.DemandModel> BugList)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirFactoryWaitingList(List<CDSBDemandControl.Model.BillingModel> Billing, bool AllowsShow)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirAlocacao(IEnumerable<CDSBDemandControl.Model.DemandModel> demandModels)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirFactoryProductionList(List<CDSBDemandControl.Model.BillingModel> Billing, bool AllowsShow)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirSolicitacoesSites(List<CDSBDemandControl.Model.DemandModel> listaView)
        {
            throw new NotImplementedException();
        }

        void IDiscriminatorDemand.ExibirManagementTeamTasks(List<CDSBDemandControl.Model.DemandModel> list)
        {
            throw new NotImplementedException();
        }

        #endregion

        protected void gridScenarios_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                GridView gv = (GridView)e.Row.FindControl("gridTasks");

                List<TaskDesenvModel> source =
                    (gridScenarios.DataSource as List<ScenarioModel>).Find
                    (delegate(ScenarioModel sc)
                    {
                        return (sc.ID == (e.Row.DataItem as ScenarioModel).ID);
                    }).RelatedLinks;

                gv.DataSource = source;

                gv.DataBind();

                /* VERMELHO
                Quando não houver tarefas linkadas para o cenário.
                Quando todas as tarefas linkadas para o cenário estão no status concluídas e Canceladas.
                Quando houver pelo menos uma tarefa com ininio estimado para a data atual ou data atual-n e ainda estiver em fila.
                Quando houver pelo menos uma tarefa com ininio estimado para a data atual ou data atual-n e ainda estiver em análise da fábrica.
                Quando houver pelo menos uma tarefa com ininio estimado para a data atual e a data de início realizada está em branco.                
                */

                string color = string.Empty;
                string reason = string.Empty;

                if (source.Count == 0)
                {
                    color = "red";
                    reason = "este scenario nao apresenta taskdesenv linkadas";
                }
                else
                {
                    foreach (TaskDesenvModel task in source)
                    {
                        if (task.Status == "Concluida" || task.Status == "Cancelada")
                        {
                            color = "red";
                            reason = "todas as tasks foram concluidas ou canceladas";
                        }
                        else
                        {
                            color = string.Empty;
                            reason = string.Empty;
                            break;
                        }
                    }

                    foreach (TaskDesenvModel task in source)
                    {
                        if (!task.EstimatedConclude.HasValue && task.Conclude.HasValue)
                        {
                            color = "red";
                            reason = task.ID + ", task com final estimado não informado e final realizado informado";
                            break;
                        }                        
                    }

                    if (string.IsNullOrEmpty(color))
                    {
                        foreach (TaskDesenvModel task in source)
                        {
                            if (task.Status == "Em Fila")
                            {
                                if (task.EstimatedStart.HasValue && task.EstimatedStart.Value.Date <= DateTime.Now.Date)
                                {
                                    color = "red";
                                    reason = task.ID + ", em fila, data inicio estimada para hoje ou anterior";
                                    break;
                                }
                            }
                            if (task.Status == "Em Analise Fabrica")
                            {
                                if (task.EstimatedStart.HasValue && task.EstimatedStart.Value.Date <= DateTime.Now.Date)
                                {
                                    color = "red";
                                    reason = task.ID + ", em analise fabrica, data inicio estimada para hoje ou anterior";
                                    break;
                                }
                            }

                            if (task.Status == "Codigo Aprovado")
                            {
                                if (!task.Conclude.HasValue)
                                {
                                    color = "red";
                                    reason = task.ID + ", codigo aprovado e termino realizado nao informado";
                                    break;
                                }
                            }

                            if (
                                (task.Status.ToLower() != "cancelada")
                            && 
                            (task.EstimatedStart.HasValue && task.EstimatedStart.Value.Date == DateTime.Now.Date && !task.Start.HasValue)
                                )
                            {
                                color = "red";
                                reason = task.ID + ", data inicio estimada para hoje e inicio realizado nao informado";
                                break;
                            }
                        }
                    }
                    /* AMARELO
                    Quando houver no mínimo uma tarefa com o status em Código aprovado e a data atual é menor que a próxima terça feira da entrega realizada da tarefa.
                    Quando houver pelo menos uma tarefa com ininio estimado menor ou igual a data atual+ 7 e ainda estiver em fila.
                    Quando houver pelo menos uma tarefa com ininio estimado menor ou igual a data atual+ 7 e ainda estiver em análise da fábrica.
                    */

                    if (string.IsNullOrEmpty(color))
                    {
                        foreach (TaskDesenvModel task in source)
                        {
                            if (task.Status == "Codigo Aprovado")
                            {
                                DateTime dtPacote = this.CalcularPacote(task.Conclude.Value);

                                if (DateTime.Now.Date < dtPacote.Date)
                                {
                                    color = "yellow";
                                    reason = task.ID + ", aguardando merge da tarefa";
                                    break;
                                }
                                else
                                {
                                    color = "red";
                                    reason = task.ID + ", não foi realizado merge da tarefa";
                                    break;
                                }
                            }

                            if (task.Status == "Em Fila")
                            {
                                if (
                                    (task.EstimatedStart.HasValue) &&
                                    ((task.EstimatedStart.Value.Date >= DateTime.Now.Date) && (task.EstimatedStart.Value.Date <= DateTime.Now.Date.AddDays(7)))
                                    )
                                {
                                    color = "yellow";
                                    reason = task.ID + ", em fila, data inicio estimada para hoje ou tres dias posteriores";
                                    break;
                                }
                            }

                            if (task.Status == "Em Analise Fabrica")
                            {
                                if (
                                    (task.EstimatedStart.HasValue) &&
                                    ((task.EstimatedStart.Value.Date >= DateTime.Now.Date) && (task.EstimatedStart.Value.Date <= DateTime.Now.Date.AddDays(7)))
                                    )
                                {
                                    color = "yellow";
                                    reason = task.ID + ", em analise fabrica, data inicio estimada para hoje ou tres dias posteriores";
                                    break;
                                }
                            }

                            if (task.Start.HasValue && task.EstimatedStart.Value.Date < task.Start.Value.Date)
                            {
                                color = "yellow";
                                reason = task.ID + ", em situação de alerta, task com atraso no início";
                                break;
                            }
                        }
                    }

                    /* VERDE
                     * Quando houver pelo menos uma task com início estimado maior que 7 dias.*/
                    if (string.IsNullOrEmpty(color))
                    {
                        foreach (TaskDesenvModel task in source)
                        {
                            if (task.EstimatedStart.HasValue && task.EstimatedStart.Value.Date > DateTime.Now.Date.AddDays(7))
                            {
                                color = "green";
                                reason = task.ID + ", com início estimado maior que 7 dias";
                                break;
                            }

                            if (task.Start.HasValue && task.EstimatedStart.Value.Date > task.Start.Value.Date)
                            {
                                color = "green";
                                reason = task.ID + ", normal, task com início anterior ao previsto";
                                break;
                            }
                        }
                    }

                }

                if (!string.IsNullOrEmpty(color))
                {
                    e.Row.BackColor = Color.FromName(color);
                    if(color != "yellow")
                        e.Row.ForeColor = Color.White;
                    e.Row.Cells[0].ToolTip = reason;

                    foreach (GridViewRow row in gv.Rows)
                    {
                        if (row.RowType == DataControlRowType.DataRow)
                        {
                            row.BackColor = Color.FromName(color);
                            if (color != "yellow")
                                row.ForeColor = Color.White;
                        }
                    }

                }
            }
        }

        private DateTime CalcularPacote(DateTime ent)
        {
            DateTime ret = DateTime.Now;

            switch (ent.DayOfWeek)
            {
                case DayOfWeek.Saturday:
                    ret = ent.AddDays(4);
                    break;
                case DayOfWeek.Sunday:
                    ret = ent.AddDays(3);
                    break;
                case DayOfWeek.Monday:
                    ret = ent.AddDays(9);
                    break;
                case DayOfWeek.Tuesday:
                    ret = ent.AddDays(8);
                    break;
                case DayOfWeek.Thursday:
                    ret = ent.AddDays(7);
                    break;
                case DayOfWeek.Wednesday:
                    ret = ent.AddDays(6);
                    break;
                case DayOfWeek.Friday:
                    ret = ent.AddDays(5);
                    break;                
            }

            return ret;
        }

        protected void Grid_DataBinding(object sender, EventArgs e)
        {
            ((GridView)sender).Visible = true;
        }
    }
}
